package chapter4.homework;

/**
 * @Project ：learn_java
 * @File ：Q3.java
 * @IDE ：IntelliJ IDEA
 * @Author ：自由如风间
 * @Date ：2025/3/8 16:28
 * @Description ：多线程题3
 *
    创建一个银行账户类Account，
        属性私有化：账号（声明为final的），余额，
        两个属性都只提供get方法
        有参构造public Account(String id, double balance)
        toString()：返回：账户：xxx，余额：xxx
        提供存钱方法 public void save(double money)，
        提供取钱方法public void withdraw(double money)，余额不足要等待

    创建一个丈夫线程类Husband，
        包含Account成员变量，
        包含public Husband(String name, Account account)构造器
        重写run方法，调用Account对象的save方法，负责往里存钱，每次存款[100,10000)以内不等金额

    创建一个妻子线程类Wife
        包含Account成员变量，
        包含public Wife(String name, Account account)构造器
        重写run方法，调用Account对象的withdraw方法，负责取钱，每次取款[1000,20000)以内不等，如果余额不足，要等丈夫存够了才能取
 */

class Account {
    private final String id;
    private double balance;

    public Account(String id, double balance) {
        this.id = id;
        this.balance = balance;
    }

    public String getId() {
        return id;
    }

    public double getBalance() {
        return balance;
    }

    // 防止多个线程同时修改导致的数据错误
    public synchronized void save(double money) {
        if (money > 0) {
            balance += money;
            System.out.println(Thread.currentThread().getName() + "存入：" + money + "元。当前余额为：" + balance + "元");
        }
    }

    public synchronized void withdraw(double money) throws InterruptedException {
        while (balance < money) {
            System.out.println("余额不足，等待存款...");
            wait(); // 等待存款
        }
        if (money > 0 && balance >= money) {
            balance -= money;
            System.out.println(Thread.currentThread().getName() + "取出：" + money + "元。当前余额为：" + balance + "元");
        }
    }

    @Override
    public String toString() {
        return "账户：" + id + "，余额：" + balance;
    }
}

class Husband extends Thread {
    private final Account account;

    public Husband(String name, Account account) {
        // 调用父类的构造函数
        super(name);
        this.account = account;
    }

    @Override
    public void run() {
        while (true) {
            double money = 100 + Math.random() * (10000 - 100);
            account.save(money);
            try {
                Thread.sleep((long)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 每次存款都会唤醒其他线程
            synchronized (account) {
                account.notifyAll();
            }
        }
    }
}

class Wife extends Thread {
    private final Account account;

    public Wife(String name, Account account) {
        super(name);
        this.account = account;
    }

    @Override
    public void run() {
        while (true) {
            double money = 1000 + Math.random() * (20000 - 1000);
            try {
                account.withdraw(money);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                // 模拟时间间隔
                Thread.sleep((long)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class Q3 {
    public static void main(String[] args) {
        Account account = new Account("1122", 1000);
        Husband husband = new Husband("阿沸", account);
        Wife wife = new Wife("阿美", account);

        husband.start();
        wife.start();
    }
}
